#encoding:utf8
import sys,datetime
from urlparse import urlparse
import re
import urllib

from DB import *
import gua
from util_func import strdecode

reload(sys)
sys.setdefaultencoding("utf8")

#全站Url解析器
class UrlParser(object) :
    def __init__(self) :
        self.city_urlname = {}
        self.country_urlname = {}
        self.continent_urlname = {}
        self.hotel_urls = {}
        self.guide_urlname = {}

    #####################################################
    #功能:根据锦囊英文名，初始化锦囊url                 #
    #输出:字典 {锦囊url名:锦囊id}                       #
    #####################################################
    def init_guide_urlname(self) :
        guide_urlname = {}
        qyer_db = DB(gua.conn_qyer["host"], gua.conn_qyer["username"], gua.conn_qyer["password"], gua.conn_qyer["db"], gua.conn_qyer["port"])
        qyer_db.execute("select id, enname from qyer.jn_info where status = 1")
        result_set = qyer_db.fetchall()
        qyer_db.close()
        for result in result_set :
            guide_id = result["id"]
            enname = result["enname"].lower()
            urlname = enname.replace("'", "").replace(" ", "-").replace("&", "and").replace(",", "-").replace(".", "")
            guide_urlname[urlname] = guide_id
        return guide_urlname

    #####################################################
    #功能:根据城市英文名，初始化城市url                 #
    #输出:字典 {城市url名:城市id}                       #
    #####################################################
    def init_city_urlname(self) :
        city_urlname = {}
        qyer_db = DB(gua.conn_qyer["host"], gua.conn_qyer["username"], gua.conn_qyer["password"], gua.conn_qyer["db"], gua.conn_qyer["port"])
        qyer_db.execute("select id, cityname, cityname_en, cityname_url from city where status = 1")
        result_set = qyer_db.fetchall()
        qyer_db.close()
        for result in result_set :
            cityid = result["id"]
            enname = result["cityname_en"].lower().strip("\t ")
            cityname_url = result["cityname_url"]
            if cityname_url : enname = cityname_url.lower().strip("\t ")
            urlname = enname.replace("'", "").replace(" ", "-").replace("&", "and").replace(",", "-").replace(".", "")
            city_urlname[urlname] = cityid
        return city_urlname

    #####################################################
    #功能:根据国家英文名，初始化国家url                 #
    #输出:字典 {国家url名:国家id}                       #
    #####################################################
    def init_country_urlname(self) :
        country_urlname = {}
        qyer_db = DB(gua.conn_qyer["host"], gua.conn_qyer["username"], gua.conn_qyer["password"], gua.conn_qyer["db"], gua.conn_qyer["port"])
        qyer_db.execute("select id, catename, catename_en from category where parentid in (select id from category where parentid = 1)")
        result_set = qyer_db.fetchall()
        for result in result_set :
            country_id = result["id"]
            enname = result["catename_en"].lower()
            urlname = enname.replace("'", "").replace(" ", "-").replace("&", "and").replace(",", "-").replace(".", "")
            country_urlname[urlname] = country_id
        return country_urlname

    #####################################################
    #功能:根据大洲英文名，初始化大洲url                 #
    #输出:字典 {大洲url名:大洲id}                       #
    #####################################################
    def init_continent_urlname(self) :
        continent_urlname = {}
        qyer_db = DB(gua.conn_qyer["host"], gua.conn_qyer["username"], gua.conn_qyer["password"], gua.conn_qyer["db"], gua.conn_qyer["port"])
        qyer_db.execute("select id, catename_en from category where parentid = 1")
        result_set = qyer_db.fetchall()
        for result in result_set :
            continent_id = result["id"]
            enname = result["catename_en"].lower()
            urlname = enname.replace("'", "").replace(" ", "-").replace("&", "and").replace(",", "-").replace(".", "")
            continent_urlname[urlname] = continent_id
        return continent_urlname
        
    #####################################################
    #功能:根据酒店对应的booking链接，初始化酒店url      #
    #输出:字典{booking链接:酒店id}                      #
    #####################################################
    def init_hotel_url(self) :
        qyer_db = DB(gua.conn_qyer["host"], gua.conn_qyer["username"], gua.conn_qyer["password"], gua.conn_qyer["db"], gua.conn_qyer["port"])
        qyer_db.execute("select id, booking_url from qyer.business_hotel where source = 1")
        result_set = qyer_db.fetchall()
        qyer_db.close()
        hotel_urls = {result["booking_url"] : result["id"] for result in result_set if result["booking_url"]}
        return hotel_urls

    ################################################################
    #功能:按产品线解析url                                          #
    #输入:url                                                      #
    #输出:字典 {”action_type":行为类型, "action_content":行为内容  #
    ################################################################
    def parse_url(self, url) :
        parsedUrl = urlparse(url)
        #web端锦囊
        if parsedUrl.netloc == "guide.qyer.com" : return self.parse_guide_url(parsedUrl.path, parsedUrl.query)
        #m端/app端锦囊
        if (parsedUrl.netloc == "m.qyer.com" or parsedUrl.netloc == "appview.qyer.com") and parsedUrl.path.startswith("/guide") : return self.parse_guide_url("/"+parsedUrl.path.split("/", 2)[-1], parsedUrl.query)
        #web端目的地
        if parsedUrl.netloc == "place.qyer.com" : return self.parse_place_url(parsedUrl.path, parsedUrl.query)
        #m端/app端目的地
        if (parsedUrl.netloc == "m.qyer.com" or parsedUrl.netloc == "appview.qyer.com") and parsedUrl.path.startswith("/place") : return self.parse_place_url("/"+parsedUrl.path.split("/", 2)[-1], parsedUrl.query)
        #web端问答
        if parsedUrl.netloc == "ask.qyer.com" : return self.parse_ask_url(parsedUrl.path, parsedUrl.query)
        #m端/app端问答
        if (parsedUrl.netloc == "m.qyer.com" or parsedUrl.netloc == "appview.qyer.com") and parsedUrl.path.startswith("/ask") : return self.parse_ask_url("/"+parsedUrl.path.split("/", 2)[-1], parsedUrl.query)
        #web端行程助手
        if parsedUrl.netloc == "plan.qyer.com" : return self.parse_plan_url(parsedUrl.path, parsedUrl.query)
        #m端/app端行程助手
        if (parsedUrl.netloc == "m.qyer.com" or parsedUrl.netloc == "appview.qyer.com") and parsedUrl.path.startswith("/plan") : return self.parse_plan_url("/"+parsedUrl.path.split("/", 2)[-1], parsedUrl.query)
        #web端论坛
        if parsedUrl.netloc == "bbs.qyer.com" : return self.parse_bbs_url(parsedUrl.path, parsedUrl.query)
        #m端/app端论坛
        if (parsedUrl.netloc == "m.qyer.com" or parsedUrl.netloc == "appview.qyer.com") and parsedUrl.path.startswith("/bbs") : return self.parse_bbs_url("/"+parsedUrl.path.split("/", 2)[-1], parsedUrl.query)
        if (parsedUrl.netloc == "m.qyer.com" or parsedUrl.netloc == "appview.qyer.com") and parsedUrl.path.startswith("/path") : return self.parse_bbs_url("/"+parsedUrl.path.split("/", 2)[-1], parsedUrl.query)
        #web端折扣
        if parsedUrl.netloc == "z.qyer.com" : return self.parse_z_url(parsedUrl.path, parsedUrl.query)
        #m端/app端折扣
        if (parsedUrl.netloc == "m.qyer.com" or parsedUrl.netloc == "appview.qyer.com") and parsedUrl.path.startswith("/z/") : return self.parse_z_url("/"+parsedUrl.path.split("/", 2)[-1], parsedUrl.query)
        #web端搜索
        if parsedUrl.netloc == "search.qyer.com" : return self.parse_search_url(parsedUrl.path, parsedUrl.query)
        #m端搜索
        if parsedUrl.netloc == "m.qyer.com" and (parsedUrl.path.startswith("/s.php") or parsedUrl.path.startswith("/search")) : return self.parse_search_url("/"+parsedUrl.path.split("/", 2)[-1], parsedUrl.query)
        #跳转booking
        if parsedUrl.path.startswith("/goto.php") and parsedUrl.query.find("booking.com") != -1 : 
            rs=self.parse_goto_hotel_url(parsedUrl.query)
            return rs
        return {"action_type":"view_others", "action_content":{}}

    ################################################################
    #功能:解析锦囊页                                               #
    #输入:path - string, 二级路径                                  #
    #     query - string, url中查询参数                            #
    #输出:字典 {”action_type":行为类型, "action_content":行为内容  #
    ################################################################
    def parse_guide_url(self, path, query) :
        if len(self.guide_urlname) == 0 : self.guide_urlname = self.init_guide_urlname()
        if not path or path == "/" : return {"action_type":"view_guide_index", "action_content":{}}
        words = path.split("/")
        if len(words) > 1 : return {"action_type":"view_guide_detail", "action_content":{"guide_name":words[1], "guide_id":self.guide_urlname.get(words[1],0)}}
        else : return {"action_type":"view_guide_others", "action_content":{}}

    ################################################################
    #功能:解析目的地页                                             #
    #输入:path - string, 二级路径                                  #
    #     query - string, url中查询参数                            #
    #输出:字典 {”action_type":行为类型, "action_content":行为内容  #
    ################################################################
    def parse_place_url(self, path, query) :
        if len(self.city_urlname) == 0 : self.city_urlname = self.init_city_urlname() 
        if len(self.country_urlname) == 0 : self.country_urlname = self.init_country_urlname()
        if len(self.continent_urlname) == 0 : self.continent_urlname = self.init_continent_urlname()
        words = path.split("/")
        if len(words) > 1 :
            if words[1] == "poi" :
                m = re.search(r"poi/(\d+)", path)
                if not m : return {"action_type":"view_poi_others", "action_content":{}}
                poi_id = int(m.group(1))
                if "photo"in path : return {"action_type": "view_poi_photo_detail", "action_content":{"poi_id":poi_id}}
                return {"action_type":"view_poi", "action_content":{"poi_id":poi_id}}
            elif words[1] in self.city_urlname :
                city_id = self.city_urlname[words[1]]
                if "mguide" in path : return {"action_type":"view_city_mguide_list", "action_content":{"city_id":city_id}}
                if "hotel" in path : return {"action_type":"view_city_hotel_list", "action_content":{"city_id":city_id}}
                if "photo" in path : return {"action_type":"view_city_photo_detail", "action_content":{"city_id":city_id}} 
                return {"action_type":"view_city", "action_content":{"city_id":city_id}}
            elif words[1] in self.country_urlname :
                country_id = self.country_urlname[words[1]]
                if "mguide" in path : return {"action_type":"view_country_mguide_list", "action_content":{"country_id":country_id}}
                if "hotel" in path : return {"action_type":"view_country_hotel_list", "action_content":{"country_id":country_id}}
                if "photo" in path : return {"action_type":"view_country_photo_detail", "action_content":{"country_id":country_id}}
                return {"action_type":"view_country", "action_content":{"country_id":country_id}}
            elif words[1] in self.continent_urlname :
                continent_id = self.continent_urlname[words[1]]
                if "mguide" in path : return {"action_type":"view_continent_mguide_list", "action_content":{"continent_id": continent_id}}
                if "hotel" in path : return {"action_type":"view_continent_hotel_list", "action_content":{"continent_id" : continent_id}}
                if "photo" in path : return {"action_type":"view_continent_hotel_list", "action_content":{"continent_id":continent_id}}
                return {"action_type":"view_continent", "action_content":{"continent_id":continent_id}}
            elif words[1] == "mguide" :
                m = re.search(r"(\d+)", path)
                if m :
                    mguide_id = int(m.group(1))
                    return {"action_type":"view_mguide_detail", "action_content":{"mguide_id":mguide_id}}
                else : return {"action_type":"view_mguide_others", "action_content":{}}
            elif words[1] == "" : return {"action_type":"view_place_index", "action_content":{}}
            else : return {"action_type":"view_place_others", "action_content":{}}
        else : return {"action_type":"view_place_index", "action_content":{}}

    ################################################################
    #功能:解析问答页                                               #
    #输入:path - string, 二级路径                                  #
    #     query - string, url中查询参数                            #
    #输出:字典 {”action_type":行为类型, "action_content":行为内容  #
    ################################################################
    def parse_ask_url(self, path, query) :
        m = re.search(r"question/(\d+)", path)
        if m :
            question_id = int(m.group(1))
            return {"action_type":"view_ask_detail", "action_content":{"qid":question_id}}
        elif path.startswith("/tag") : 
            temps = path.split("/")
            if len(temps) >= 3 : return {"action_type":"view_ask_tag", "action_content":{"tag":temps[2]}}
            else : return {"action_type":"view_ask_tag", "action_content":{"tag":""}}
        elif path.startswith("/search") :
            query_url = urllib.unquote(urllib.unquote(query))
            search_result = self.parse_search(query_url)
            return {"action_type":"search_ask", "action_content":search_result}
        else : return {"action_type":"view_ask_list", "action_content":{}}


    ################################################################
    #功能:解析行程助手页                                           #
    #输入:path - string, 二级路径                                  #
    #     query - string, url中查询参数                            #
    #输出:字典 {”action_type":行为类型, "action_content":行为内容  #
    ################################################################
    def parse_plan_url(self, path, query) :
        if "/create" in path : return {"action_type":"create_plan", "action_content":{}} 
        if "/smartcreate" in path : return {"action_type":"smartcreate_plan", "action_content":{}}
        if path.startswith("/search") :
            query_url = urllib.unquote(urllib.unquote(query)) 
            search_result = self.parse_search(query_url)
            temps = path.split("_")
            if len(temps) >= 4 : search_result["countryids"] = [int(temps[3])]
            return {"action_type":"search_plan", "action_content":search_result}
        if "/calendar" in path or "/cost" in path or "/message" in path or "/map" in path or "/traffic" in path or "/hotel" in path :
            m = re.search(r"/(\d+)/", path)
            if m  :
                plan_id = int(m.group(1))
                return {"action_type":"view_plan_detail", "action_content":{"plan_id":plan_id}}
            else : return {"action_type":"view_plan_detail", "action_content":{}}
        m = re.search(r"trip/(\d+)", path)
        if m : 
            plan_id = int(m.group(1))
            if "edit" in path : return {"action_type":"edit_plan", "action_content":{"plan_id":plan_id}}
            else : return {"action_type":"view_plan_detail", "action_content":{"plan_id":plan_id}} 
        else :
            m = re.search(r"tripapp/(\d+)", path)
            if m : 
                plan_id = int(m.group(1))
                return {"action_type":"view_plan_detail", "action_content":{"plan_id":plan_id}}
            else :
                m = re.search(r"poi_(\d+)", path)
                if m :
                    poi_id = int(m.group(1))
                    return {"action_type":"view_place_poi", "action_content":{"poi_id":poi_id}}
                else : return {"action_type":"view_plan_others", "action_content":{}}

    ################################################################
    #功能:解析论坛页                                               #
    #输入:path - string, 二级路径                                  #
    #     query - string, url中查询参数                            #
    #输出:字典 {”action_type":行为类型, "action_content":行为内容  #
    ################################################################
    def parse_bbs_url(self, path, query) :
        if "post.php" in path : return {"action_type":"post_thread", "action_content":{}}
        if "search.php" in path : 
            query_url = urllib.unquote(urllib.unquote(query))
            search_result = self.parse_search(query_url)
            return {"action_type":"search_bbs", "action_content":search_result}
        tid = 0
        m = re.search(r"thread-(\d+)-", path)
        if m : tid = int(m.group(1))
        else :
            m = re.search(r"tid=(\d+)", query)
            if m : tid = int(m.group(1))
        if tid : return {"action_type":"view_thread", "action_content":{"tid":tid}}
        fid = 0
        m = re.search(r"forum-(\d+)", path)
        if m : fid = int(m.group(1))
        if fid : return {"action_type":"view_bbs_forum", "action_content":{"fid":fid}}
        return {"action_type":"view_bbs_others", "action_content":{}} 

    ################################################################
    #功能:解析折扣页                                               #
    #输入:path - string, 二级路径                                  #
    #     query - string, url中查询参数                            #
    #输出:字典 {”action_type":行为类型, "action_content":行为内容  #
    ################################################################
    def parse_z_url(self, path, query) :
        query_url = urllib.unquote(urllib.unquote(query))
        product_type_ids = {"flights":1016, "hotels":1017, "free":1018, "freetour":1018, "cruise":1020, "car":1021, "safe":1049, "qz":1785, "local":2410, "ot":2161, "other":1050, "cityfun":2410}
        m = re.search(r"/deal/(\d+)", path)
        if m : 
            lm_id = int(m.group(1))
            return {"action_type":"view_lm_detail", "action_content":{"lm_id":lm_id}}
        elif path.startswith("/zt") :
            temps = path.split("/")
            if len(temps) >= 3 : return {"action_type":"view_lm_zt", "action_content":{"zt_name":temps[2]}}
            else : return {"action_type":"view_lm_zt", "action_content":{"zt_name":""}}
        elif path.startswith("/sup") :
            temps = path.split("/")
            if len(temps) >= 3 : 
                if temps[2].isdigit() : return {"action_type":"view_lm_sup", "action_content":{"sup_id":int(temps[2])}}
                elif temps[-1].isdigit() : return {"action_type":"view_lm_sup", "action_content":{"sup_id":int(temps[-1])}}
            else : return {"action_type":"view_lm_sup", "action_content":{"sup_id":0}}
        elif path.startswith("/orderform") : return {"action_type":"lm_orderfom"}
        else :
            m = re.search("action=orderform&lid=(\d+)", query) 
            if m : return {"action_type":"lm_orderform", "action_content":{"lm_id":int(m.group(1))}}
        if query.startswith("ptype") or query.startswith("dpt") or query.startswith("date") or query.startswith("continent") or query.startswith("cnty") or query.startswith("kw") or query.startswith("turn") :
            params = query_url.split("&")
            search_type = 0
            dept = 0
            travel_time = 0
            continent_id = 0
            country_id = 0
            city_id = 0
            kw = ""
            for param in params :
                try : k, v = param.split("=")
                except : continue
                if k == "ptype" : search_type = product_type_ids.get(v, 0)
                elif k == "dpt" : dept = int(v) if v.isdigit() else  0
                elif k == "date" : travel_time = int(v) if v.isdigit() else 0
                elif k == "continent" : continent_id = int(v) if v.isdigit() else 0
                elif k == "cnty" : country_id = int(v) if v.isdigit() else 0
                elif k == "country" : country_id = int(v) if v.isdigit() else 0
                elif k == "city" : city_id = int(v) if v.isdigit() else  0
                elif k == "kw" : kw = v
            return {"action_type":"view_lm_list", "action_content":{"product_type":search_type, "dpt":dept, "travel_time":travel_time, "continent_id":continent_id, "country_id":country_id, "city_id":city_id, "kw":kw}}
        else :
            m = re.search("(\d+)_(\d+)_(\d+)_(\d+)", path)
            if m : 
                if path.startswith("/free") or path.startswith("/qz") or path.startswith("/hotels") or path.startswith("/flights") or path.startswith("/other") or path.startswith("/cruise") or path.startswith("/car") or path.startswith("/safe") or path.startswith("/local") or path.startswith("/ot") or path.startswith("/cityfun"): 
                    #print path
                    name = path.split("/")[1]
                    if name in product_type_ids :
                        search_type = product_type_ids[name]
                        temps = path.split("/")[2:]
                    else :
                        name = name.split("_")[0]
                        if name in product_type_ids :
                            search_type = product_type_ids[name]
                            temps = ["all_" + path.split("_", 1)[1]]
                        else : return {"action_type":"view_lm_list", "action_content":{"product_type":0, "dpt":0, "travel_time":0, "continent_id":0, "country_id":country_id, "city_id":city_id, "kw":""}}
                    #print "xxx", search_type, temps
                else : 
                    if query.startswith("_channel=cityfun") : search_type = product_type_ids["local"]
                    else : search_type = 0
                    temps = path.split("/")[1:]
                dept = 0
                travel_time = 0
                continent_id = 0
                country_id = 0
                city_id = 0
                if len(temps) :
                    temp = temps[0].split("_")
                    if len(temp) == 4 :
                        try : dept = int(temp[0])
                        except : dept = 0
                        try : travel_time = int(temp[1])
                        except : travel_time = 0
                        try : continent_id = int(temp[2])
                        except : continent_id = 0
                        try : country_id = int(temp[3])
                        except : country_id = 0
                        if country_id == 1966 : country_id = 11; city_id = 50
                        elif country_id == 1967 : country_id = 11; city_id = 51
                        elif country_id == 1968 : country_id = 11; city_id = 11186
                    else :
                        try : dept = int(temp[1])
                        except : dept = 0
                        try : travel_time = int(temp[2])
                        except : travel_time = 0
                        #try : continent_id = temp[3]
                        #except : continent_id = 0
                        try : country_id = temp[3]
                        except : country_id = 0
                        try : city_id = temp[4] 
                        except : city_id = 0
                return {"action_type":"view_lm_list", "action_content":{"product_type":search_type, "dpt":dept, "travel_time": travel_time, "continent_id":continent_id, "country_id":country_id, "city_id":city_id, "kw":""}}
            elif path.startswith("/free") or path.startswith("/qz") or path.startswith("/hotels") or path.startswith("/flights") or path.startswith("/other") or path.startswith("/cruise") or path.startswith("/car") or path.startswith("/safe") or path.startswith("/local") or path.startswith("/ot") or path.startswith("/cityfun"): 
                search_type = product_type_ids[path.split("/")[1]]
                return {"action_type":"view_lm_list", "action_content":{"product_type":search_type, "dpt":0, "travel_time":0, "content_id":0, "country_id":0, "city_id":0, "kw":""}}
            m = re.search("aciton=detail&id=(\d+)", query)
            if m : return {"action_type":"view_lm_detail", "action_content":{"lm_id":int(m.group(1))}}
            else : return {"action_type":"view_lm_others", "action_content":{}}
                    
    ################################################################
    #功能:解析搜索页                                               #
    #输入:path - string, 二级路径                                  #
    #     query - string, url中查询参数                            #
    #输出:字典 {”action_type":行为类型, "action_content":行为内容  #
    ################################################################
    def parse_search_url(self, path, query) :
        if path.startswith("/index") : search_range = "all"
        elif path.startswith("/bbs") : search_range = "bbs"
        elif path.startswith("/plan") : search_range = "plan"
        elif path.startswith("/lastminute") : search_range = "lm"
        elif path.startswith("/ask") : search_range = "ask"
        elif path.startswith("/user") : search_range = "user"
        elif path.startswith("/hotel") : search_range = "hotel"
        else : search_range = "all"
        m = re.search(r"(\d+)", path)
        if m : return {"action_type":"search_%s" % search_range, "action_content":{"wd_code":int(m.group(1))}}
        query_url = urllib.unquote(urllib.unquote(query))
        search_result = self.parse_search(query_url)
        return {"action_type":"search_%s" % search_range, "action_content":search_result}

    ################################################################
    #功能:解析搜索页                                               #
    #输入:path - string, 二级路径                                  #
    #     query - string, url中查询参数                            #
    #输出:字典 {”action_type":行为类型, "action_content":行为内容  #
    ################################################################
    def parse_search(self, query) :
        search_result = {}
        m = re.search(ur"(wd|q|tags|keyword)=([^&]*)", query)
        if m : search_result["wd"] = m.group(2)
        m = re.search(r"(cityid)=([\d,]+)", query)
        if m : 
            city_ids = map(int, m.group(2).split(","))
            search_result["cityids"] = city_ids
        return search_result
    
    ################################################################
    #功能:解析跳转酒店页                                           #
    #输入:path - string, 二级路径                                  #
    #     query - string, url中查询参数                            #
    #输出:字典 {”action_type":行为类型, "action_content":行为内容  #
    ################################################################
    def parse_goto_hotel_url(self, query) :
        if len(self.hotel_urls) == 0 : 
            self.hotel_urls = self.init_hotel_url()
            
        query_url = urllib.unquote(urllib.unquote(query))
        m = re.search("hotelid=(\d+)", query_url)
        rs=None
        if m :
            hotel_id = int(m.group(1))
            rs={"action_type":"goto_hotel", "action_content":{"hotel_id":hotel_id}}
        else :
            m = re.search("url=([^?]+)", query_url)
            if m :
                booking_url = m.group(1)
                hotel_id = self.hotel_urls.get(booking_url, 0)
                if hotel_id : 
                    rs={"action_type":"goto_hotel", "action_content":{"hotel_id":hotel_id}}
        return rs if rs else {"action_type":"goto_hotel", "action_content":{}}
